package com.example.excise06.security;

import com.example.excise06.entity.UserEntity;
import com.example.excise06.entity.UserRoleEntity;
import com.example.excise06.repository.UserRepository;
import com.example.excise06.repository.UserRoleRepository;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class UserDetailServiceImpl implements UserDetailsService {
    private final UserRepository userRepository;
    private final UserRoleRepository userRoleRepository;
    public UserDetailServiceImpl(UserRepository userRepository, UserRoleRepository userRoleRepository){
        this.userRepository =userRepository;
        this.userRoleRepository = userRoleRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        // 1. 根据登录名获取用户账户数据
        Optional<UserEntity> userEntityOptional = this.userRepository.findByLogin(s);
        if (!userEntityOptional.isPresent()) {
            throw new UsernameNotFoundException("登录名[" + s + "]的账户不存在");
        }
        UserEntity userEntity = userEntityOptional.get();
        // 2. 获取账户对应角色
        List<UserRoleEntity> roles = this.userRoleRepository.findByUserLogin(userEntity.getLogin());
        // 将角色拼接为数组
        String[] roleNames = new String[roles.size()];
        for (Integer i = 0; i < roles.size(); i++) {
            roleNames[i] = roles.get(i).getRoleName();
        }
        // 3. 构造为SpringSecurity的验证，并返回交给Spring Security进行校验
        User user = new User(
                userEntity.getLogin(),
                userEntity.getPassword(),
                Arrays.stream(roleNames).map(SimpleGrantedAuthority::new).collect(Collectors.toList())
        );
        //将通过登录名拿到的user交给SpringSecurity进行校验
        return user;
    }
}